﻿#include "SudokuMaker.h"
#include "SudokuChecker.h"
#include "SudokuPrinter.h"

using namespace std;


namespace SudokuMaker
{
	bool is_exit = false;
	
	void prtSudoku()
	{
		if (is_exit)
			return;
		++num_of_sudoku;
		/*
		int err = checkSudoku(sudoku);
		if (err != 0)
		{
			cout << "wrong!" << endl;
		}
		*/

		if (num_of_sudoku == upper_limit_of_sudoku)
		{
			printSudoku(sudoku, true);
			CloseHandle(h_sudoku_txt);
			is_exit = true;
		}
		else
			printSudoku(sudoku, false);

	}

	//交换两行
	void swapRow(int n, int m)
	{
		/*for (int i = 0; i < 10; i++)
		{
			std::swap(sudoku[n][i], sudoku[m][i]);
		}*/
		std::swap(sudoku[n], sudoku[m]);
	}

	void generateFullSwappedRowSudoku(int level)
	{
		if (is_exit)
			return;
		//2、3行相互交换
		if (level == 0)
		{
			generateFullSwappedRowSudoku(level + 1);//不交换2、3
			swapRow(2, 3);
			generateFullSwappedRowSudoku(level + 1);//交换2、3
		}
		//4、5、6行相互交换
		else
			if (level == 1)
			{
				generateFullSwappedRowSudoku(level + 1);//不进行交换

				swapRow(4, 5);
				generateFullSwappedRowSudoku(level + 1);

				swapRow(4, 6);
				generateFullSwappedRowSudoku(level + 1);

				swapRow(5, 6);
				generateFullSwappedRowSudoku(level + 1);

				swapRow(4, 5);
				generateFullSwappedRowSudoku(level + 1);

				swapRow(4, 6);
				generateFullSwappedRowSudoku(level + 1);
			}
		//7、8、9行相互交换
			else
			{
				prtSudoku();//不进行交换
				swapRow(7, 8);
				prtSudoku();
				swapRow(7, 9);
				prtSudoku();
				swapRow(8, 9);
				prtSudoku();
				swapRow(7, 8);
				prtSudoku();
				swapRow(7, 9);
				prtSudoku();
			}

		return;
	}

	//根据第一行生成一个基本数独
	void generateSingleSudoku()
	{
		//生成第2、3行
		for (int row = 2; row < 4; row++)
		{
			//不使用求余或者if以加快速度，尽管实现丑陋
			for (int column = 1; column < 7; column++)
			{
				sudoku[row][column] = sudoku[row - 1][column + 3];
			}
			for (int column = 7; column < N_ROW_SUDOKU; column++)
			{
				sudoku[row][column] = sudoku[row - 1][column - 6];
			}
		}
		//生成4——9行
		for (int row = 4; row < N_ROW_SUDOKU; row++)
		{
			for (int column = 1; column < 9; column++)
			{
				sudoku[row][column] = sudoku[row - 3][column + 1];
			}
			sudoku[row][9] = sudoku[row - 3][1];
		}
	}

	void generateFullPermutation(int* used, int n)
	{
		if (is_exit)
			return;
		if (n == N_ROW_SUDOKU)
		{
			generateSingleSudoku();
			generateFullSwappedRowSudoku(0);
			return;
		}
		//生成数独的第一行的全排列共8!种
		//因为第一个数字必须是7，所以跳过7
		for (int i = 1; i < 7; i++)
		{
			if (used[i] == 0)
			{
				used[i] = 1;
				sudoku[1][n] = i;
				generateFullPermutation(used, n + 1);
				used[i] = 0;
			}
		}
		for (int i = 8; i < N_ROW_SUDOKU; i++)
		{
			if (used[i] == 0)
			{
				used[i] = 1;
				sudoku[1][n] = i;
				generateFullPermutation(used, n + 1);
				used[i] = 0;
			}
		}
	}
}

void makeSudoku()
{
	int used[N_ROW_SUDOKU];
	for (int i = 1; i < N_ROW_SUDOKU; i++)
	{
		used[i] = 0;
		sudoku[1][i] = i;
	}
	swap(sudoku[1][1], sudoku[1][7]);
	SudokuMaker::generateFullPermutation(used, 2);
}
